package com.fengycx.temlate;

import cn.hutool.json.JSONUtil;
import com.fengycx.dto.SearchDriverDto;
import com.fengycx.properties.GeoProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.geo.*;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.GeoOperations;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.ArrayList;
import java.util.List;

@Configuration
public class RedisGeoTemplate {

    private RedisTemplate redisTemplate;

    private GeoProperties geoProperties;


    public RedisGeoTemplate(RedisTemplate redisTemplate, GeoProperties geoProperties) {
         this.redisTemplate=redisTemplate;
         this.geoProperties=geoProperties;
    }


    public List<SearchDriverDto> searchDriverGeo(String key, double longitude, double latitude){
        //定义中心点的经纬度
        Point center = new Point(longitude,latitude);
        //定义搜索半径
        Circle circle = new Circle(center, new Distance(geoProperties.getRadius(), Metrics.KILOMETERS));
        //geo搜索的参数
        RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs();
        //结果中包含 距离
        args.includeDistance()
                //结果中包含坐标
                .includeCoordinates()
                //根据中心点按照从近到远排序
                .sortAscending()
                //匹配前几个司机
                .limit(geoProperties.getDriverCount());

        //执行GEO搜索 (key是大key 司机的位置Key)
        GeoOperations<String,Long> geoOperations = redisTemplate.opsForGeo();
        GeoResults<RedisGeoCommands.GeoLocation<Long>> geoResults = geoOperations.radius(key, circle, args);

        //获得符合条件的 司机名称 距离中心点的距离
        List<SearchDriverDto> searchDriverResult = geoResults.getContent().stream().map(r -> {
            double distance = r.getDistance().getValue();
            String driverId = JSONUtil.toJsonStr(r.getContent().getName());
            return new SearchDriverDto(Long.valueOf(driverId),distance) ;
        }).toList();

        return searchDriverResult;
    }
}
